package org.ppassantini.cham.core.inteceptor;

/*
 * (C) 2007 Mark Menard & Vita Rara, Inc.
 *
 * Mark Menard and Vita Rara, Inc. licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.StrutsStatics;
import org.ppassantini.cham.core.business.security.dto.MenuDto;
import org.ppassantini.cham.core.security.SecurityManager;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * A Struts 2 interceptor that implements a login system.
 */
public class LoginInterceptor extends AbstractInterceptor implements StrutsStatics {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3719207330832080613L;
	private SecurityManager securityManager;
	
	private static final Log log = LogFactory.getLog (LoginInterceptor.class);
	private static final String USER_HANDLE = "QUADRAN_USER_SESSSION_HANDLE";
	private static final String LOGIN_ATTEMPT = "QUADRAN_LOGIN_ATTEMPT";
	private static final String USERNAME = "QUADRAN_USERNAME";
	private static final String PASSWORD = "QUADRAN_PASSWORD";

	public void init () {
		log.info ("Intializing LoginInterceptor");
	}

	public void destroy () {}

	public String intercept (ActionInvocation invocation) throws Exception {
		// Get the action context from the invocation so we can access the
		// HttpServletRequest and HttpSession objects.
		final ActionContext context = invocation.getInvocationContext ();
		HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
		HttpSession session =  request.getSession (true);

		// Is there a "user" object stored in the user's HttpSession?
		Object user = session.getAttribute (USER_HANDLE);
		if (user == null) {
			// The user has not logged in yet.

			// Is the user attempting to log in right now?
			String loginAttempt = request.getParameter (LOGIN_ATTEMPT);
			if (! StringUtils.isBlank (loginAttempt) ) { // The user is attempting to log in.

				// Process the user's login attempt.
				if (processLoginAttempt (request, session) ) {
					// The login succeeded send them the login-success page.
					return "login-success";
				} else {
					// The login failed. Set an error if we can on the action.
					Object action = invocation.getAction ();
					if (action instanceof com.opensymphony.xwork2.ValidationAware) {
						String message = ((ActionSupport)invocation.getAction()).getText("global.login.incorrect");
						((com.opensymphony.xwork2.ValidationAware) action).addActionError (message);
					}
				}
			}

			// Either the login attempt failed or the user hasn't tried to login yet, 
			// and we need to send the login form.
			return "login";
		} else {
			return invocation.invoke ();
		}
	}

	/**
	 * Attempt to process the user's login attempt delegating the work to the 
	 * SecurityManager.
	 */
	public boolean processLoginAttempt (HttpServletRequest request, HttpSession session) {
		// Get the username and password submitted by the user from the HttpRequest.
		String username = request.getParameter (USERNAME);
		String password = request.getParameter (PASSWORD);

		// Use the security manager to validate the user's username and password.
		Object user = securityManager.login (username, password);

		if (user != null) {
			// The user has successfully logged in. Store their user object in 
			// their HttpSession. Then return true.
			session.setAttribute (USER_HANDLE, user);
			session.setAttribute ("mainMenu",getMenu(username));
			return true;
		} else {
			// The user did not successfully log in. Return false.
			return false;
		}
	}

	/**
	 * @param username
	 * @return
	 */
	private List<MenuDto> getMenu(String username){
		
		return ((List<MenuDto>) securityManager.getMenuUser(username));
	
	}
	
	/**
	 * @param in
	 */
	public void setSecurityManager (SecurityManager in) {
		log.debug ("Setting security manager using: " + in.toString () );
		this.securityManager = in;
	}

		
}
